package xyz.ck.commons.interval;

import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import xyz.ck.commons.util.SyntaxException;

public class IntervalFormat extends Format {

	private Class<?> clazz = null;

	private boolean continous = false;

	private Format format = null;

	public static final DateFormat defaultDateFormat = DateFormat
			.getDateInstance(1);

	public IntervalFormat() {
		super();
	}

	public IntervalFormat(Format format, boolean continous) {
		super();
	}

	public static IntervalFormat getInstance(Format format, boolean continous) {
		return new IntervalFormat(format, continous);
	}

	public static IntervalFormat getIntegerInstance() {
		IntervalFormat instance = new IntervalFormat();
		instance.clazz = Integer.class;
		instance.continous = false;
		return instance;
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 4217532853815746448L;

	@Override
	public StringBuffer format(Object obj, StringBuffer toAppendTo,
			FieldPosition pos) {

		if (this.format == null) {
			throw new IntervalException("you Must define an format!");
		}

		toAppendTo.append(this.format.format(obj, toAppendTo, pos));
		return toAppendTo;
	}

	protected String[] split(String source) {
		if (this.continous) {
			return source.split(",");
		}

		return source.split("[\\]\\)]\\s*,\\s*[\\[\\(] ");

	}

	@Override
	public Object parseObject(String source, ParsePosition pos) {

		return parse(source, pos);
	}

	public <T> Interval<T> parse(String source, ParsePosition pos) {
		int start = pos.getIndex();
		String sub1 = source.substring(start);

		String[] strs = sub1.split(Constant.groupDelemeter);

		for (int i = 0; i < strs.length; i++) {
			String item = strs[i];
			String[] sstrs = item.split(Constant.delemeter);

			if (sstrs.length == 1) {
				// TODO resolve [1] 1 point!
			} else if (sstrs.length == 2) {
				// TODO common [1~13) or 1~33
			} else {
				// ignore the released
			}

		}

		return null;
	}

	public <T> List<Interval<T>> parse(String[] strs, Class<T> clazz) {

		List<Interval<T>> list = new ArrayList<>();
		for (int i = 0; i < strs.length; i++) {
			if (Integer.class.isAssignableFrom(this.clazz)) {
				@SuppressWarnings("unchecked")
				Interval<T> unit = (Interval<T>) parseInt(strs[i]);
				list.add(unit);
			} else if (Long.class.isAssignableFrom(this.clazz)) {
				@SuppressWarnings("unchecked")
				Interval<T> unit = (Interval<T>) parseLong(strs[i]);
				list.add(unit);
			} else if (Float.class.isAssignableFrom(this.clazz)) {
				@SuppressWarnings("unchecked")
				Interval<T> unit = (Interval<T>) parseFloat(strs[i]);
				list.add(unit);
			} else if (Double.class.isAssignableFrom(this.clazz)) {
				@SuppressWarnings("unchecked")
				Interval<T> unit = (Interval<T>) parseDouble(strs[i]);
				list.add(unit);
			} else if (Double.class.isAssignableFrom(this.clazz)) {
				@SuppressWarnings("unchecked")
				Interval<T> unit = (Interval<T>) parseDouble(strs[i]);
				list.add(unit);
			} else if (Date.class.isAssignableFrom(this.clazz)) {
				try {
					@SuppressWarnings("unchecked")
					Interval<T> unit = (Interval<T>) parseDate(strs[i],
							defaultDateFormat);
					list.add(unit);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		return list;

	}

	public <T> List<Interval<T>> parseContinous(String strs, Class<T> clazz) {
		return null;
	}

	private static IntervalUnit<Integer> parseInt(String strs) {
		if (strs == null || strs.isEmpty()) {
			return null;
		}

		strs = strs.replaceAll("\\+", "-" + Integer.MAX_VALUE);
		String[] items = strs.split("~");
		if (items == null) {
			return null;
		}
		if (items.length == 1) {
			int num = Integer.parseInt(items[0].trim());
			return new IntervalUnit<Integer>(num, num);

		}

		if (items.length == 2) {
			int min = Integer.parseInt(items[0].trim());
			int max = Integer.parseInt(items[1].trim());
			return new IntervalUnit<Integer>(min, max);

		}
		throw new SyntaxException("syntax Error: espect 10-20 or 15 an so on! ");

	}

	private static IntervalUnit<Long> parseLong(String strs) {
		if (strs == null || strs.isEmpty()) {
			return null;
		}

		strs = strs.replaceAll("\\+", "-" + Integer.MAX_VALUE);
		String[] items = strs.split("~");
		if (items == null) {
			return null;
		}
		if (items.length == 1) {
			Long num = Long.parseLong(items[0].trim());
			return new IntervalUnit<Long>(num, num);

		}

		if (items.length == 2) {
			Long min = Long.parseLong(items[0].trim());
			Long max = Long.parseLong(items[1].trim());
			return new IntervalUnit<Long>(min, max);

		}
		throw new SyntaxException("syntax Error: espect 10-20 or 15 an so on! ");

	}

	private static IntervalUnit<Float> parseFloat(String strs) {
		if (strs == null || strs.isEmpty()) {
			return null;
		}

		strs = strs.replaceAll("\\+", "-" + Integer.MAX_VALUE);
		String[] items = strs.split("~");
		if (items == null) {
			return null;
		}
		if (items.length == 1) {
			Float num = Float.parseFloat(items[0].trim());
			return new IntervalUnit<Float>(num, num);

		}

		if (items.length == 2) {
			Float min = Float.parseFloat(items[0].trim());
			Float max = Float.parseFloat(items[1].trim());
			return new IntervalUnit<Float>(min, max);

		}
		throw new SyntaxException("syntax Error: espect 10-20 or 15 an so on! ");

	}

	private static IntervalUnit<Double> parseDouble(String strs) {
		if (strs == null || strs.isEmpty()) {
			return null;
		}

		strs = strs.replaceAll("\\+", "-" + Integer.MAX_VALUE);
		String[] items = strs.split("~");
		if (items == null) {
			return null;
		}
		if (items.length == 1) {
			Double num = Double.parseDouble(items[0].trim());
			return new IntervalUnit<Double>(num, num);

		}

		if (items.length == 2) {
			Double min = Double.parseDouble(items[0].trim());
			Double max = Double.parseDouble(items[1].trim());
			return new IntervalUnit<Double>(min, max);

		}
		throw new SyntaxException("syntax Error: espect 10-20 or 15 an so on! ");
	}

	private static IntervalUnit<Date> parseDate(String strs,
			DateFormat dateFormat) throws ParseException {
		if (strs == null || strs.isEmpty()) {
			return null;
		}

		strs = strs.replaceAll("\\+", "-" + Integer.MAX_VALUE);
		String[] items = strs.split("~");
		if (items == null) {
			return null;
		}
		if (items.length == 1) {
			Date date = dateFormat.parse(items[0]);
			return new IntervalUnit<Date>(date, date);

		}

		if (items.length == 2) {
			Date min = dateFormat.parse(items[0].trim());
			Date max = dateFormat.parse(items[1].trim());
			return new IntervalUnit<Date>(min, max);

		}
		throw new SyntaxException("syntax Error: espect 10-20 or 15 an so on! ");
	}

	public static void main(String[] args) throws ParseException {
		NumberFormat nf = NumberFormat.getInstance();
		nf.setGroupingUsed(true);
		nf.setParseIntegerOnly(false);
		Number number = nf.parse("1 2367 5111.123231");
		number.intValue();
		System.out.println(number.getClass() + " " + number.toString() + " "
				+ nf.format(number));

		// String strs = "-123.12 ~ 23.13,123~114 ";

		String strs1 = "(-123.12 , 23.13],(123,  114  ],[  123, 89   ) ";

		StringTokenizer token = new StringTokenizer(strs1);

		int index = 0;

		while (token.hasMoreElements()) {
			String left = token.nextToken();

			String right = token.nextToken();

			left = left.trim();

			boolean leftClose;
			Object object = null;

			boolean rightClose;
			if (left.charAt(0) == '[') {

			}

			index++;
		}

		System.out.println(token.nextToken(","));

		System.out.println(token.nextToken());
		System.out.println(token.nextToken());
		System.out.println(token.nextToken());
		System.out.println(token.nextToken());
		System.out.println(token.nextToken());
		// Interval<Integer> a = IntervalGroup.unions(new
		// IntervalUnit<Integer>(9,
		// 11), new IntervalUnit<Integer>(1, 5),
		// new IntervalUnit<Integer>(3, 7));
		//
		// IntervalFormat format = new IntervalFormat();
		// String texta = format.format(a);
		// System.out.println(texta);
		// Interval<Double> b = IntervalGroup.unions(
		// new ContinousIntervalUnit<Double>(true, 9d, 11d, false),
		// new ContinousIntervalUnit<Double>(true, 1d, 5d, true),
		// new ContinousIntervalUnit<Double>(false, 3d, 7d, false));
		//
		// String textb = format.format(b);
		// System.out.println(textb);

	}
}
